home *** CD-ROM | disk | FTP | other *** search
/ Deutsche Edition 1 / Deutsche Edition 1.iso / amok / 011-020 / amok19 / trackdisksupport / trackdisksupport.mod < prev    next >
Text File  |  1993-11-04  |  11KB  |  394 lines

  1. (**********************************************************************
  2.  
  3.     :Program.    TrackDiskSupport.mod
  4.     :Contents.   Support to access trackdisk sectors
  5.     :Author.     Fridtjof Siebert [fbs]
  6.     :Address.    [fbs] Nobileweg 67, D7000 Stuttgart 40
  7.     :Phone.      [fbs] (0)711/822509
  8.     :Author.     Nicolas Benezan [bne]
  9.     :Address.    [bne] Postwiesenstr. 2, D7000 Stuttgart 60
  10.     :Phone.      [bne] 0711/333679
  11.     :Copyright.  Public Domain, no commercial use !!!
  12.     :Language.   Modula-2
  13.     :Translator. M2Amiga A+L V3.2d
  14.     :Imports.    DosSupport1.3, TaskMemory [bne]
  15.     :History.    V1.0 [fbs] 5.Dez.1988
  16.     :History.    V1.1 [bne] 12.May.1989 (adapted m2c V3.2d)
  17.     :History.    V2.0 [bne] 13.May.1989 (+other drivetypes, DHx: etc.)
  18.     :Remark.     Hi Fridtjof, my V2.0 code is 18% smaller! [bne]
  19.     :History.    V2.1 [bne] 14.May.1989 (+ InhibitDrive)
  20.  
  21. **********************************************************************)
  22. IMPLEMENTATION MODULE TrackDiskSupport;
  23.  
  24. FROM Arts        IMPORT Assert, TermProcedure, DetectCtrlC;
  25. FROM Dos         IMPORT DeviceListType, ProcessPtr, StandardPacket,
  26.                         inhibit;
  27. FROM DosSupport  IMPORT BPTRtoADR, BSTRtoStr, GetDevList, StartupInfoPtr,
  28.                         DiskInfoPtr, DeviceListPtr;
  29. FROM Exec        IMPORT DoIO, OpenDevice, CloseDevice, MsgPortPtr, Byte,
  30.                         FindTask, PutMsg, WaitPort, GetMsg, message;
  31. FROM ExecSupport IMPORT CreatePort, DeletePort, CreateExtIO, DeleteExtIO;
  32. FROM SYSTEM      IMPORT ADR, LONGSET, ADDRESS, BITSET, BPTR, CAST;
  33. FROM TaskMemory  IMPORT Allocate, Deallocate;
  34. FROM TrackDisk   IMPORT motor, seek, changeNum, changeState, extClear,
  35.                         protStatus, getDriveType, getNumTracks,
  36.                         extRead, extWrite, extUpdate, extFormat,
  37.                         trackDiskName, IOTrackDisk, IOTrackDiskPtr,
  38.                         badDriveType, noMem;
  39.  
  40. TYPE
  41.   DiskUnit=POINTER TO DiskUnitRec;
  42.   DiskUnitRec=RECORD
  43.     link:DiskUnit;
  44.     replyPort:MsgPortPtr;
  45.     reqBlock:IOTrackDiskPtr;
  46.     info:DeviceInfo;
  47.   END;
  48.  
  49. VAR
  50.   OpenList:DiskUnit;
  51.  
  52. (*­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­*)
  53. (* Scan Dos device list and open the device                             *)
  54. (*­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­*)
  55. PROCEDURE OpenDiskDevice(    DeviceName: ARRAY OF CHAR;
  56.                          VAR Unit: DiskUnit): Byte;
  57.   VAR
  58.     Error: Byte;
  59.     DeviceNode:DeviceListPtr;
  60.  
  61.   PROCEDURE ScanDeviceList():BOOLEAN;
  62.     CONST
  63.       nul=CHR(0);
  64.     VAR
  65.       DevName:Name;
  66.       Pos:INTEGER;
  67.     BEGIN
  68.       DeviceNode:=GetDevList();
  69.       LOOP
  70.         IF DeviceNode=NIL THEN
  71.           RETURN FALSE
  72.         END;
  73.         WITH DeviceNode^ DO
  74.           IF type=device THEN
  75.             BSTRtoStr(name,DevName);
  76.             Pos:=0;
  77.             WHILE DevName[Pos]=DeviceName[Pos] DO
  78.               IF (DevName[Pos]=nul) AND (DeviceName[Pos]=nul) THEN
  79.                 RETURN TRUE
  80.               END;
  81.               INC(Pos);
  82.             END;
  83.           END;
  84.           DeviceNode:=BPTRtoADR(next);
  85.         END;
  86.       END;
  87.     END ScanDeviceList;
  88.  
  89.   PROCEDURE ReadDevInfo():BOOLEAN;
  90.     VAR
  91.       Startup:StartupInfoPtr;
  92.     BEGIN
  93.       WITH Unit^.info DO
  94.         handler:=DeviceNode^.task;
  95.         Startup:=BPTRtoADR(CAST(BPTR,DeviceNode^.startup));
  96.         IF Startup=NIL THEN
  97.           RETURN FALSE
  98.         END;
  99.         WITH Startup^ DO
  100.           BSTRtoStr(execName,devName);
  101.           devUnit :=unit;
  102.           devFlags:=flags;
  103.           disk:=BPTRtoADR(diskInfo);
  104.         END;
  105.         IF (disk=NIL) OR (disk^.length<11) THEN
  106.           RETURN FALSE
  107.         END;
  108.         WITH disk^ DO
  109.           blockLen   :=blockSize*4;        (* longword = 4 bytes *)
  110.           trackLen   :=blockLen*numSecs;
  111.           cylinderLen:=trackLen*surfaces;
  112.           numBlocks  :=(highCyl-lowCyl+1)*surfaces*numSecs;
  113.           offset     :=lowCyl*cylinderLen; (* partition origin *)
  114.         END;
  115.       END;
  116.       RETURN TRUE;
  117.     END ReadDevInfo;
  118.  
  119.   BEGIN
  120.     Error:=noMem;
  121.     DetectCtrlC(FALSE);
  122.     TrackDiskAllocProc(Unit,SIZE(Unit^));
  123.     IF Unit#NIL THEN
  124.       Error:=badDriveType;
  125.       IF ScanDeviceList() AND ReadDevInfo() THEN
  126.         WITH Unit^ DO
  127.           replyPort:=CreatePort(NIL,0);
  128.           IF replyPort#NIL THEN
  129.             reqBlock:=CreateExtIO(replyPort,SIZE(IOTrackDisk));
  130.             IF reqBlock#NIL THEN
  131.               OpenDevice(ADR(info.devName),info.devUnit,reqBlock,info.devFlags);
  132.               Error:=reqBlock^.req.error;
  133.               IF Error=0 THEN
  134.                 link:=OpenList;   (* add node *)
  135.                 OpenList:=Unit;
  136.                 DetectCtrlC(TRUE);
  137.                 RETURN 0;
  138.               END;
  139.               DeleteExtIO(reqBlock);
  140.             END;
  141.             DeletePort(replyPort);
  142.           END;
  143.         END; (* WITH Unit^ *)
  144.       END;
  145.       TrackDiskDeallocProc(Unit);
  146.     END;
  147.     DetectCtrlC(TRUE);
  148.     RETURN Error;
  149.   END OpenDiskDevice;
  150.  
  151. PROCEDURE CloseDiskDevice(Unit: DiskUnit);
  152.   VAR
  153.     Prev,Node:DiskUnit;
  154.   BEGIN
  155.     Prev:=ADR(OpenList);
  156.     Node:=OpenList;
  157.     WHILE Node#Unit DO
  158.       Prev:=Node;
  159.       Node:=Node^.link;
  160.       Assert(Node#NIL,ADR("CloseDiskDevice: no unit"));
  161.     END;
  162.     WITH Unit^ DO
  163.       Prev^.link:=link;     (* remove node *)
  164.       CloseDevice(reqBlock);
  165.       DeleteExtIO(reqBlock);
  166.       DeletePort(replyPort);
  167.     END;
  168.     TrackDiskDeallocProc(Unit);
  169.   END CloseDiskDevice;
  170.  
  171. PROCEDURE GetDeviceInfo(    Unit: DiskUnit;
  172.                         VAR Info: DeviceInfo);
  173.   BEGIN
  174.     Info:=Unit^.info;
  175.   END GetDeviceInfo;
  176.  
  177. PROCEDURE DoRequest(ReqBlock:IOTrackDiskPtr;
  178.                         Command:CARDINAL);
  179.   BEGIN
  180.     ReqBlock^.req.command:=Command;
  181.     DetectCtrlC(FALSE);
  182.     DoIO(ReqBlock);
  183.     DetectCtrlC(TRUE);
  184.   END DoRequest;
  185.  
  186. PROCEDURE GetDiskChange(Unit: DiskUnit): LONGINT;
  187.   BEGIN
  188.     WITH Unit^ DO
  189.       DoRequest(reqBlock,changeNum);
  190.       RETURN reqBlock^.req.actual;
  191.     END;
  192.   END GetDiskChange;
  193.  
  194. PROCEDURE ChangeState(Unit: DiskUnit): BOOLEAN;
  195.   BEGIN
  196.     WITH Unit^ DO
  197.       DoRequest(reqBlock,changeState);
  198.       RETURN reqBlock^.req.actual=0;
  199.     END;
  200.   END ChangeState;
  201.  
  202. PROCEDURE ProtStatus(Unit: DiskUnit): BOOLEAN;
  203.   BEGIN
  204.     WITH Unit^ DO
  205.       DoRequest(reqBlock,protStatus);
  206.       RETURN reqBlock^.req.actual=0;
  207.     END;
  208.   END ProtStatus;
  209.  
  210. PROCEDURE Motor(Unit: DiskUnit; On: BOOLEAN): BOOLEAN;
  211.   BEGIN
  212.     WITH Unit^ DO
  213.       IF On THEN
  214.         reqBlock^.req.length:=1;
  215.       ELSE
  216.         reqBlock^.req.length:=0;
  217.       END;
  218.       DoRequest(reqBlock,motor);
  219.       RETURN reqBlock^.req.actual=1;
  220.     END;
  221.   END Motor;
  222.  
  223. PROCEDURE Seek(Unit: DiskUnit; BlockNum: LONGINT): Byte;
  224.   BEGIN
  225.     WITH Unit^ DO
  226.       reqBlock^.req.offset:=BlockNum*info.blockLen + info.offset;
  227.       DoRequest(reqBlock,seek);
  228.       RETURN reqBlock^.req.error;
  229.     END;
  230.   END Seek;
  231.  
  232. PROCEDURE ReadBlock(Unit: DiskUnit;
  233.                     Block: LONGINT;
  234.                     NumBlocks: CARDINAL;
  235.                     Buffer: ADDRESS;
  236.                     ChangeCnt: LONGINT): Byte;
  237.  BEGIN
  238.     WITH Unit^ DO
  239.       WITH reqBlock^ DO
  240.         req.data  :=Buffer;
  241.         req.length:=LONGINT(NumBlocks)*info.blockLen;
  242.         req.offset:=Block*info.blockLen + info.offset;
  243.         count     :=ChangeCnt;
  244.         secLabel  :=NIL;
  245.       END;
  246.       DoRequest(reqBlock,extRead);
  247.       RETURN reqBlock^.req.error;
  248.     END;
  249.   END ReadBlock;
  250.  
  251. PROCEDURE WriteBlock(Unit: DiskUnit;
  252.                      Block: LONGINT;
  253.                      NumBlocks: CARDINAL;
  254.                      Buffer: ADDRESS;
  255.                      ChangeCnt: LONGINT): Byte;
  256.   BEGIN
  257.     WITH Unit^ DO
  258.       WITH reqBlock^ DO
  259.         req.data  :=Buffer;
  260.         req.length:=LONGINT(NumBlocks)*info.blockLen;
  261.         req.offset:=Block*info.blockLen + info.offset;
  262.         count     :=ChangeCnt;
  263.         secLabel  :=NIL;
  264.       END;
  265.       DoRequest(reqBlock,extWrite);
  266.       RETURN reqBlock^.req.error;
  267.     END;
  268.   END WriteBlock;
  269.  
  270. PROCEDURE Update(Unit: DiskUnit;
  271.                  ChangeCnt: LONGINT): Byte;
  272.   BEGIN
  273.     WITH Unit^ DO
  274.       reqBlock^.count:=ChangeCnt;
  275.       DoRequest(reqBlock,extUpdate);
  276.       RETURN reqBlock^.req.error;
  277.     END;
  278.   END Update;
  279.  
  280. PROCEDURE FormatTrack(Unit: DiskUnit;
  281.                       Cylinder: CARDINAL;
  282.                       Head: CARDINAL;
  283.                       Buffer: ADDRESS;
  284.                       ChangeCnt: LONGINT): Byte;
  285.   VAR
  286.     TrackSize:LONGINT;
  287.   BEGIN
  288.     WITH Unit^ DO
  289.       WITH reqBlock^ DO
  290.         req.length:=info.trackLen;
  291.         req.offset:=LONGINT(Head)*info.trackLen +
  292.                     LONGINT(Cylinder)*info.cylinderLen +
  293.                     info.offset;
  294.         req.data  :=Buffer;
  295.         count     :=ChangeCnt;
  296.       END;
  297.       DoRequest(reqBlock,extFormat);
  298.       RETURN reqBlock^.req.error;
  299.     END;
  300.   END FormatTrack;
  301.  
  302. PROCEDURE Clear(Unit: DiskUnit): Byte;
  303.   BEGIN
  304.     WITH Unit^ DO
  305.       DoRequest(reqBlock,extClear);
  306.       RETURN reqBlock^.req.error;
  307.     END;
  308.   END Clear;
  309.  
  310. PROCEDURE GetDriveType(Unit: DiskUnit): LONGINT;
  311.   BEGIN
  312.     WITH Unit^ DO
  313.       DoRequest(reqBlock,getDriveType);
  314.       RETURN reqBlock^.req.actual;
  315.     END;
  316.   END GetDriveType;
  317.  
  318. PROCEDURE GetNumTracks(Unit: DiskUnit): LONGINT;
  319.   BEGIN
  320.     WITH Unit^ DO
  321.       DoRequest(reqBlock,getNumTracks);
  322.       RETURN reqBlock^.req.actual;
  323.     END;
  324.   END GetNumTracks;
  325.  
  326. PROCEDURE BlockNumber(Unit: DiskUnit;
  327.                       Cylinder, Sector, Head: LONGINT): LONGINT;
  328.   BEGIN
  329.     WITH Unit^.info DO
  330.       RETURN (Cylinder * cylinderLen + Head * trackLen)/blockLen + Sector;
  331.     END;
  332.   END BlockNumber;
  333.  
  334. PROCEDURE InhibitDrive(Unit: DiskUnit;
  335.                        Inhibit: BOOLEAN): BOOLEAN;
  336.   VAR
  337.     Packet:POINTER TO StandardPacket;
  338.     ThisProcess:ProcessPtr;
  339.     ReplyPort:MsgPortPtr;
  340.     Ok:BOOLEAN;
  341.   BEGIN
  342.     ThisProcess:=CAST(ProcessPtr,FindTask(NIL));
  343.     ReplyPort:=ADR(ThisProcess^.msgPort);
  344.     TrackDiskAllocProc(Packet,SIZE(Packet^));
  345.     IF Packet#NIL THEN
  346.       WITH Packet^ DO
  347.         WITH msg DO
  348.           node.type:=message;
  349.           node.pri :=0;
  350.           node.name:=ADR(pkt);
  351.           replyPort:=ReplyPort;
  352.           length   :=SIZE(Packet^);
  353.         END;
  354.         WITH pkt DO
  355.           link:=ADR(msg);
  356.           port:=ReplyPort;
  357.           type:=inhibit;
  358.           IF Inhibit THEN
  359.             arg1:=1;
  360.           ELSE
  361.             arg1:=0;
  362.           END;
  363.         END;
  364.       END;
  365.       PutMsg(Unit^.info.handler,Packet);
  366.       WaitPort(ReplyPort);
  367.       Packet:=GetMsg(ReplyPort);
  368.       WITH Packet^.pkt DO
  369.         Ok:=res1#0;
  370.         ThisProcess^.result2:=res2;
  371.       END;
  372.       TrackDiskDeallocProc(Packet);
  373.     END;
  374.     RETURN Ok;
  375.   END InhibitDrive;
  376.  
  377. PROCEDURE CleanUp;
  378.   VAR
  379.     Next:DiskUnit;
  380.   BEGIN
  381.     WHILE OpenList#NIL DO
  382.       Next:=OpenList^.link;
  383.       CloseDiskDevice(OpenList);
  384.       OpenList:=Next;
  385.     END;
  386.   END CleanUp;
  387.  
  388. BEGIN
  389.   OpenList:=NIL;
  390.   TrackDiskAllocProc:=Allocate;
  391.   TrackDiskDeallocProc:=Deallocate;
  392.   TermProcedure(CleanUp);
  393. END TrackDiskSupport.
  394.